package strategy

import "fmt"

type PaymentContext struct {
	Name, CardId string
	Money        int
}

type PaymentStrategy interface {
	Pay(ctx *PaymentContext)
}

type Payment struct {
	Context  *PaymentContext
	Strategy PaymentStrategy
}

func NewPayment(name, cardId string, money int, strategy PaymentStrategy) *Payment {
	return &Payment{
		Context: &PaymentContext{
			Name:   name,
			CardId: cardId,
			Money:  money,
		},
		Strategy: strategy,
	}
}

func (p *Payment) Pay() {
	// Strategy is interface, so it depends on its concrete implement
	p.Strategy.Pay(p.Context)
}

type Cash struct {
}

func (*Cash) Pay(ctx *PaymentContext) {
	fmt.Printf("Cash pay %v to %v\n", ctx.Money, ctx.Name)
}

type Bank struct {
}

func (*Bank) Pay(ctx *PaymentContext) {
	fmt.Printf("Online Bank pay %v to %v\n", ctx.Money, ctx.Name)
}
